package com.wgke.bluetooth.view;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class PressureMatrixRenderer implements GLSurfaceView.Renderer {
    private static final int WIDTH = 180;
    private static final int HEIGHT = 200;

    // 投影矩阵
    private final float[] mProjectionMatrix = new float[16];
    // 视图矩阵
    private final float[] mViewMatrix = new float[16];
    // 模型矩阵
    private final float[] mModelMatrix = new float[16];
    // MVP矩阵
    private final float[] mMVPMatrix = new float[16];

    // 压力数据
    private float[] mPressureData = new float[WIDTH * HEIGHT];

    // 顶点缓冲
    private FloatBuffer mVertexBuffer;
    // 颜色缓冲
    private FloatBuffer mColorBuffer;

    // 着色器程序
    private int mProgram;

    // 渲染模式 (true为3D模式，false为2D模式)
    private boolean mIs3DMode = false;

    // 点大小 (用于2D模式)
    private float mPointSize = 5.0f;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 初始化OpenGL设置
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);

        // 初始化着色器
        initShaders();

        // 初始化测试数据
        initTestData();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        // 设置透视投影
        if (mIs3DMode) {
            Matrix.perspectiveM(mProjectionMatrix, 0, 45, (float) width / height, 0.1f, 100.0f);
        } else {
            // 2D模式使用正交投影
            Matrix.orthoM(mProjectionMatrix, 0, -1, 1, -1, 1, 0.1f, 100.0f);
        }

        // 设置相机位置
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // 初始化模型矩阵 - 3D模式倾斜15度，2D模式不倾斜
        Matrix.setIdentityM(mModelMatrix, 0);
        if (mIs3DMode) {
            Matrix.rotateM(mModelMatrix, 0, 15.0f, 1.0f, 0.0f, 0.0f);
        }
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // 计算MVP矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

        // 绘制压力矩阵
        drawPressureMatrix();
    }

    private void initShaders() {
        // 顶点着色器代码
        String vertexShaderCode =
                "uniform mat4 uMVPMatrix;" +
                        "attribute vec4 vPosition;" +
                        "attribute vec4 vColor;" +
                        "varying vec4 fColor;" +
                        "uniform float uPointSize;" +  // 新增点大小uniform
                        "void main() {" +
                        "  gl_Position = uMVPMatrix * vPosition;" +
                        "  fColor = vColor;" +
                        "  gl_PointSize = uPointSize;" +  // 设置点大小
                        "}";

        // 片段着色器代码
        String fragmentShaderCode =
                "precision mediump float;" +
                        "varying vec4 fColor;" +
                        "void main() {" +
                        "  gl_FragColor = fColor;" +
                        "}";

        // 加载着色器
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        // 创建OpenGL ES程序
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);
    }

    private int loadShader(int type, String shaderCode) {
        int shader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
        return shader;
    }

    private void initTestData() {
        // 生成测试数据 (0-100)
        Random random = new Random();
        for (int i = 0; i < WIDTH * HEIGHT; i++) {
            mPressureData[i] = random.nextFloat() * 100.0f;
        }

        // 也可以创建特定模式的数据用于测试
        // 例如中心高压区域
        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                float dist = (float) Math.sqrt(Math.pow(x - WIDTH/2, 2) + Math.pow(y - HEIGHT/2, 2));
                mPressureData[y * WIDTH + x] = Math.max(0, 100 - dist/2);
            }
        }
    }

    private void drawPressureMatrix() {
        // 每个点的高度缩放因子 (Y轴的1/5)
        float heightScale = mIs3DMode ? 1.0f / 5.0f : 0.0f;

        // 计算顶点和颜色数据
        float[] vertices = new float[WIDTH * HEIGHT * 3];
        float[] colors = new float[WIDTH * HEIGHT * 4];

        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                int index = y * WIDTH + x;
                float pressure = mPressureData[index];

                // 顶点位置 (x, y, z)
                vertices[index * 3] = (x - WIDTH/2.0f) / WIDTH * 2.0f;  // X: -1 到 1
                vertices[index * 3 + 1] = (pressure / 100.0f) * heightScale; // Y: 根据压力值(3D模式)或0(2D模式)
                vertices[index * 3 + 2] = (y - HEIGHT/2.0f) / HEIGHT * 2.0f; // Z: -1 到 1

                // 颜色 (根据压力值)
                if (pressure < 10) {
                    // 蓝色 (0,0,1)
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = 0.0f;
                    colors[index * 4 + 2] = 1.0f;
                    colors[index * 4 + 3] = 1.0f;
                } else if (pressure < 50) {
                    // 蓝色到绿色渐变
                    float t = (pressure - 10) / 40.0f;
                    colors[index * 4] = 0.0f;
                    colors[index * 4 + 1] = t;
                    colors[index * 4 + 2] = 1.0f - t;
                    colors[index * 4 + 3] = 1.0f;
                } else if (pressure < 85) {
                    // 绿色到黄色渐变
                    float t = (pressure - 50) / 35.0f;
                    colors[index * 4] = t;
                    colors[index * 4 + 1] = 1.0f;
                    colors[index * 4 + 2] = 0.0f;
                    colors[index * 4 + 3] = 1.0f;
                } else {
                    // 黄色到红色渐变
                    float t = (pressure - 85) / 15.0f;
                    colors[index * 4] = 1.0f;
                    colors[index * 4 + 1] = 1.0f - t;
                    colors[index * 4 + 2] = 0.0f;
                    colors[index * 4 + 3] = 1.0f;
                }
            }
        }

        // 创建顶点缓冲
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        mVertexBuffer = bb.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        // 创建颜色缓冲
        ByteBuffer cb = ByteBuffer.allocateDirect(colors.length * 4);
        cb.order(ByteOrder.nativeOrder());
        mColorBuffer = cb.asFloatBuffer();
        mColorBuffer.put(colors);
        mColorBuffer.position(0);

        // 使用程序
        GLES20.glUseProgram(mProgram);

        // 获取属性位置
        int positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        int colorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");
        int mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        int pointSizeHandle = GLES20.glGetUniformLocation(mProgram, "uPointSize");

        // 传递MVP矩阵
        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mMVPMatrix, 0);

        // 传递点大小 (2D模式使用较大点，3D模式使用较小点)
        float pointSize = mIs3DMode ? 2.0f : mPointSize;
        GLES20.glUniform1f(pointSizeHandle, pointSize);

        // 启用顶点属性
        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glEnableVertexAttribArray(colorHandle);

        // 设置顶点数据
        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, mVertexBuffer);
        GLES20.glVertexAttribPointer(colorHandle, 4, GLES20.GL_FLOAT, false, 0, mColorBuffer);

        // 绘制点
        GLES20.glDrawArrays(GLES20.GL_POINTS, 0, WIDTH * HEIGHT);

        // 禁用顶点属性
        GLES20.glDisableVertexAttribArray(positionHandle);
        GLES20.glDisableVertexAttribArray(colorHandle);
    }

    /**
     * 切换2D/3D模式
     * @param is3DMode true为3D模式，false为2D模式
     */
    public void set3DMode(boolean is3DMode) {
        mIs3DMode = is3DMode;

        // 2D模式禁用深度测试，3D模式启用
        if (mIs3DMode) {
            GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        } else {
            GLES20.glDisable(GLES20.GL_DEPTH_TEST);
        }
    }

    /**
     * 获取当前是否为3D模式
     * @return true为3D模式，false为2D模式
     */
    public boolean is3DMode() {
        return mIs3DMode;
    }

    /**
     * 设置2D模式下点的大小
     * @param size 点的大小(像素)
     */
    public void setPointSize(float size) {
        mPointSize = size;
    }

    /**
     * 获取2D模式下点的大小
     * @return 点的大小(像素)
     */
    public float getPointSize() {
        return mPointSize;
    }
}